// 中国大陆的18位身份证号码校验
//#region 
// ^[1-9]\d{5}：表示地区码，6位数字，首位数字不能为0。
// (18|19|20)\d{2}：表示年份，范围为1800-2099。
// (0[1-9]|1[0-2])：表示月份，01-12月。
// (0[1-9]|[12]\d|3[01])：表示日期，01-31日。
// \d{3}(\d|X|x)：表示顺序码和校验码，顺序码为3位数字，校验码为数字或字母X/x。
//#endregion
const validateIDNo = (id) => {
  // 定义身份证号码的正则表达式
  const regex =
    /^(^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x)$)$/;

  // 测试身份证号码是否符合正则表达式
  if (!regex.test(id)) {
    return false;
  }

  // 进行校验码验证
  //#region 
  //     在中国的18位身份证号码中，最后一位是校验码，用来验证前17位的正确性。校验码的生成是通过特定的算法计算得出的
  //     取前17位数字：身份证的前17位是按地区、出生日期和顺序码排列的。
  // 加权因子：每一位数字都有一个对应的加权因子，顺序如下：
  // 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
  // 加权求和：将前17位数字与其对应的加权因子相乘，然后求和。
  // 取模计算：将上一步的和除以11，得到余数。
  // 校验码表：根据余数查找对应的校验码，校验码表如下：
  // 余数：0 1 2 3 4 5 6 7 8 9 10
  // 校验码：1 0 X 9 8 7 6 5 4 3 2
  // 比较校验码：计算出的校验码应该与身份证号码的最后一位匹配，如果匹配则身份证号码有效，否则无效。
  //#endregion
  const checkCode = (idCard) => {
    const weightFactors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    const checkDigits = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];

    let sum = 0;
    for (let i = 0; i < 17; i++) {
      sum += idCard[i] * weightFactors[i];
    }

    const mod = sum % 11;
    return checkDigits[mod];
  };

  // 验证最后一位校验码
  if (idCard[17].toUpperCase() !== checkCode(idCard)) {
    return false;
  }

  return true;
};

export {
  validateIDNo
}